/*
 * CMediaWriter.h
 *
 *  Created on: 2017年3月5日
 *      Author: chuanjiang.zh
 */

#ifndef CMEDIAWRITER_H_
#define CMEDIAWRITER_H_

#include "MediaWriter.h"
#include "AudioTranscoder.h"
#include "SharedPtr.h"
#include "TCriticalSection.h"
#include "TByteBuffer.h"

namespace av
{





class CMediaWriter: public MediaWriter
{
public:
	CMediaWriter();
	virtual ~CMediaWriter();

	virtual bool open(const char* filename, const MFormat& fmt);

	virtual void close();

	virtual bool isOpen();

	virtual bool getFormat(MFormat& fmt);

    virtual bool writeVideo(uint8_t* data, int size, int64_t pts, int flags);

    virtual bool writeAudio(uint8_t* data, int size, int64_t pts, int flags);

    virtual int getDuration();

    virtual int64_t getByteLength();

    virtual bool setFile(const char* filepath);

    virtual bool setOutputAudioCodec(int codecId);

	virtual void setListener(MediaWriterListener* listener);

	virtual bool setMeta(const char* key, const char* value, int size);

protected:
    typedef std::shared_ptr<AudioTranscoder>	AudioTranscoderPtr;

protected:
    bool openIOContext(const char* filename);
    void closeIOContext();

    bool openFile();
    void closeFile();
    bool isFileOpen();

    bool isG711(const MediaFormat& fmt);
    bool isMp4(AVFormatContext* fmtCtx);

    void writeVideo(AVPacket& inPkt);
    void writeAudio(AVPacket& inPkt);
    void doWriteAudio(AVPacket* pkt, int rate);

	void fireStatus(int status);

protected:
    comn::CriticalSection   m_cs;

    MediaFormat m_fmt;

    std::string m_fileName;
    bool	m_changeFile;

    AVFormatContext*	m_fmtCtx;
    AVIOContext*        m_ioCtx;

    int m_videoIndex;
    int m_audioIndex;

    int64_t m_videoStartTime;
    int64_t m_videoCurrentTime;
    int64_t m_audioStartTime;
    int64_t m_audioCurrentTime;

    AudioTranscoderPtr	m_transcoder;
    bool    m_doAudioTranscode;
    comn::ByteBuffer    m_audioBuffer;
    AVCodecID	m_audioCodecId;

    int64_t	m_byteCount;

	MediaWriterListener*	m_listener;
};





} /* namespace av */

#endif /* CMEDIAWRITER_H_ */
